package com.hsoft.zhxy.common.filter;

import com.hsoft.zhxy.common.exception.BizException;
import com.hsoft.zhxy.common.exception.ExcpCodeInfoEnum;
import com.hsoft.zhxy.common.system.service.SystemService;
import com.hsoft.zhxy.common.util.HttpRequestLocal;
import com.hsoft.zhxy.common.util.JwtTokenUtils;
import com.hsoft.zhxy.common.util.KMPUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


@Log4j2
@WebFilter(filterName="authFilter",urlPatterns="/*")
public class AuthFilter implements Filter {

    @Value("${zhxy.auth}")
    private String auth;

    @Value("${zhxy.auth.yhid}")
    private String yhid;

    @Value("${zhxy.auth.yhxm}")
    private String yhxm;

    @Autowired
    SystemService systemService;

    @Autowired
    private HttpRequestLocal httpRequestLocal;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;

        // 初始化yhid和yhxm
        String httpRequestLocal_yhid = "";
        String httpRequestLocal_yhxm = "";

        // 全局校验开关为开启状态
        if( "1".equals(auth) ){

            // 获取JWTToken数据
            String jwtToken = request.getHeader("token");
            httpRequestLocal_yhid = JwtTokenUtils.checkJWT(jwtToken);

            // 如果yhid不为空，通过yhid获取用户的基本信息和权限信息
            String authUriCollectionStr = null;
            if(StringUtils.isNotBlank(httpRequestLocal_yhid)){
                authUriCollectionStr = systemService.findQqljListString(httpRequestLocal_yhid);
                httpRequestLocal_yhxm = systemService.getYhxx(httpRequestLocal_yhid);
            }

            // 获取目标资源uri
            String path = request.getServletPath();

            // 获取系统内全部的资源信息集合 SysAllQxljSet   /xtgl_03_01/yhgl/,/xtgl_03_01/yhgl1/,/xtgl_03_01/yhgl2/,/xtgl_03_01/yhgl3/,
            List<String> sysAllQxljSet = systemService.findSysAllQxljList();

            // 遍历SysAllQxljSet，KMP判断是否有能够跟path匹配的字符串，并返回 “当前path所对应的权限字符串”: qxUri
            // 当前path所对应的权限字符串:qxUri
            String qxUri = "";
            Iterator<String> iterator = sysAllQxljSet.iterator();
            while (iterator.hasNext()) {
                String str = iterator.next();
                if(KMPUtils.matchString(path, str)) {
                    qxUri = str;
                    break;
                }
            }

            // 根据“当前path所对应的权限字符串:qxUri”判断该资源是否需要权限验证。返回值类型：0-不需要验证，1-需要验证，""-不受权限集管理
            String isAuth = "";
            if(StringUtils.isNotBlank(qxUri)){
                isAuth = systemService.getSfpdqx(qxUri);
            }

            // 全局校验开关为开启状态 && 受权限集管理并且需要权限校验
            if("1".equals(auth) && "1".equals(isAuth)){
                // 如果yhid为空   ->  抛出权限异常(用户登录已过期)
                if( StringUtils.isBlank(httpRequestLocal_yhid) ){
                    throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0230);
                }
                // 如果yhid不为空 && 权限校验失败   ->  抛出权限异常(未授权)
                if( StringUtils.isNotBlank(httpRequestLocal_yhid) && (StringUtils.isBlank(authUriCollectionStr)|| !KMPUtils.matchString(authUriCollectionStr,qxUri)) ){
                    throw new BizException(ExcpCodeInfoEnum.USER_ERROR_A0301);
                }
            }
        }
        // 全局校验开关为关闭状态，则写入默认用户ID和姓名
        if( "0".equals(auth) ){
            httpRequestLocal_yhid = yhid;
            httpRequestLocal_yhxm = yhxm;
        }

        // 写入用户ID和姓名
        request.setAttribute("httpRequestLocal_yhid", httpRequestLocal_yhid);
        request.setAttribute("httpRequestLocal_yhxm", httpRequestLocal_yhxm);
        // 会话保持
        httpRequestLocal.set(request);
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);

    }

    @Override
    public void destroy() {

    }

}